﻿using System;
using System.Collections.Generic;
using System.Linq;

#if !WINRT
using System.Windows.Media;
#else
using Windows.UI;
#endif

namespace MishraReader
{
    public static class ColorExtensions
    {
        public static string GetHexadecimalValue(this Color c)
        {
            return String.Format("#{0}{1}{2}{3}", c.A.ToString("X2"), c.R.ToString("X2"), c.G.ToString("X2"), c.B.ToString("X2"));
        }

        public static Color GetColorFromHexValue(string hexValue)
        {
            byte alpha;
            byte pos = 0;

            var hex = hexValue.Replace("#", "");

            if (hex.Length == 8)
            {
                alpha = Convert.ToByte(hex.Substring(pos, 2), 16);
                pos = 2;
            }
            else
            {
                alpha = Convert.ToByte("ff", 16);
            }

            var red = Convert.ToByte(hex.Substring(pos, 2), 16);

            pos += 2;
            var green = Convert.ToByte(hex.Substring(pos, 2), 16);

            pos += 2;
            var blue = Convert.ToByte(hex.Substring(pos, 2), 16);

            return Color.FromArgb(alpha, red, green, blue);
        }

        public static Color ToColor(this Hsv hsv)
        {
            var h = hsv.Hue/360;
            if (hsv.Saturation > 0)
            {
                if (h >= 1)
                    h = 0;
                h = 6*h;
                var hueFloor = (int)Math.Floor(h);
                var a = (byte)Math.Round(255*hsv.Value*(1.0 - hsv.Saturation));
                var b = (byte)Math.Round(255*hsv.Value*(1.0 - (hsv.Saturation*(h - hueFloor))));
                var c = (byte)Math.Round(255*hsv.Value*(1.0 - (hsv.Saturation*(1.0 - (h - hueFloor)))));
                var d = (byte)Math.Round(255*hsv.Value);

                switch (hueFloor)
                {
                    case 0:
                        return Color.FromArgb(255, d, c, a);
                    case 1:
                        return Color.FromArgb(255, b, d, a);
                    case 2:
                        return Color.FromArgb(255, a, d, c);
                    case 3:
                        return Color.FromArgb(255, a, b, d);
                    case 4:
                        return Color.FromArgb(255, c, a, d);
                    case 5:
                        return Color.FromArgb(255, d, a, b);
                    default:
                        return Color.FromArgb(0, 0, 0, 0);
                }
            }
            else
            {
                var d = (byte)(hsv.Value*255);
                return Color.FromArgb(255, d, d, d);
            }
        }

        public static Hsv ToHSV(this Color c)
        {
            var r = (c.R/255.0);
            var g = (c.G/255.0);
            var b = (c.B/255.0);

            var max = Math.Max(r, Math.Max(g, b));
            var min = Math.Min(r, Math.Min(g, b));

            var h = 0.0;
            if (max == r && g >= b)
            {
                h = 60*(g - b)/(max - min);
            }
            else if (max == r && g < b)
            {
                h = 60*(g - b)/(max - min) + 360;
            }
            else if (max == g)
            {
                h = 60*(b - r)/(max - min) + 120;
            }
            else if (max == b)
            {
                h = 60*(r - g)/(max - min) + 240;
            }

            if (Double.IsNaN(h))
                h = 0;

            var s = (max == 0) ? 0.0 : (1.0 - (min/max));

            return new Hsv(h, s, max);
        }
    }
}